﻿using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace SW.Lite.Infrastructure.Helpers
{
    /// <summary>
    ///     安全辅助类
    /// </summary>
    public class SecurityHelper
    {
        private static SecurityHelper _instance;

        /// <summary>
        ///     The _arr desiv
        /// </summary>
        private byte[] _arrDesiv;

        /// <summary>
        ///     The _arr DES key
        /// </summary>
        private byte[] _arrDesKey;

        /// <summary>
        ///     Gets the instance.
        /// </summary>
        public static SecurityHelper Instance
        {
            get { return _instance ?? (_instance = new SecurityHelper()); }
        }

        /// <summary>
        ///     用于对称算法的密钥。
        /// </summary>
        /// <value>The arr DES key.</value>
        public byte[] ArrDesKey
        {
            get
            {
                if (_arrDesKey != null && (_arrDesKey.Length > 0)) return _arrDesKey;

                var sKey = ConfigHelper.Instance.Security.Key;
                if (String.IsNullOrEmpty(sKey))
                    sKey = "Strong";
                _arrDesKey = Encoding.UTF8.GetBytes(sKey);
                return _arrDesKey;
            }
        }

        /// <summary>
        ///     用于对称算法的初始化向量。
        /// </summary>
        /// <value>The arr desiv.</value>
        public byte[] ArrDesiv
        {
            get
            {
                if (_arrDesiv != null && _arrDesiv.Length >= 0) return _arrDesiv;

                var sIv = ConfigHelper.Instance.Security.IV;
                if (String.IsNullOrEmpty(sIv))
                    sIv = "World";
                _arrDesiv = Encoding.UTF8.GetBytes(sIv);
                return _arrDesiv;
            }
        }

        /// <summary>
        ///     加密数据
        /// </summary>
        /// <param name="text">加密明文</param>
        /// <returns>System.String.</returns>
        /// <exception cref="ArgumentNullException">text</exception>
        /// <exception cref="System.ArgumentNullException">text</exception>
        public string DesEncrypt(string text)
        {
            if (String.IsNullOrEmpty(text))
                throw new ArgumentNullException("text");

            var objDes = new DESCryptoServiceProvider();
            var objMemoryStream = new MemoryStream();
            var objCryptoStream = new CryptoStream(objMemoryStream, objDes.CreateEncryptor(ArrDesKey, ArrDesiv),
                CryptoStreamMode.Write);
            var objStreamWriter = new StreamWriter(objCryptoStream);
            objStreamWriter.Write(text);
            objStreamWriter.Flush();
            objCryptoStream.FlushFinalBlock();
            objMemoryStream.Flush();
            return Convert.ToBase64String(objMemoryStream.GetBuffer(), 0, (int) objMemoryStream.Length);
        }

        /// <summary>
        ///     解密。
        /// </summary>
        /// <param name="text">解密密文</param>
        /// <returns>System.String.</returns>
        /// <exception cref="ArgumentNullException">text</exception>
        /// <exception cref="System.ArgumentNullException">text</exception>
        public string DesDecrypt(string text)
        {
            if (String.IsNullOrEmpty(text))
                throw new ArgumentNullException("text");

            var objDes = new DESCryptoServiceProvider();
            var arrInput = Convert.FromBase64String(text);
            var objMemoryStream = new MemoryStream(arrInput);
            var objCryptoStream = new CryptoStream(objMemoryStream, objDes.CreateDecryptor(ArrDesKey, ArrDesiv),
                CryptoStreamMode.Read);
            var objStreamReader = new StreamReader(objCryptoStream);
            return objStreamReader.ReadToEnd();
        }

        /// <summary>
        ///     MD5加密
        /// </summary>
        /// <param name="encyptStr">加密明文</param>
        /// <returns>System.String.</returns>
        public string Md5Encrypt(string encyptStr)
        {
            var m5 = new MD5CryptoServiceProvider();
            var inputBye = Encoding.ASCII.GetBytes(encyptStr);
            var outputBye = m5.ComputeHash(inputBye);
            var retStr = Convert.ToBase64String(outputBye);
            return retStr;
        }

        /// <summary>
        ///     SHA1加密
        /// </summary>
        /// <param name="encyptStr">加密明文</param>
        /// <returns>System.String.</returns>
        public string Sha1Encrypt(string encyptStr)
        {
            var sha1 = new SHA1CryptoServiceProvider();
            var inputBye = Encoding.ASCII.GetBytes(encyptStr);
            var outputBye = sha1.ComputeHash(inputBye);
            var retStr = Convert.ToBase64String(outputBye);
            return retStr;
        }

        /// <summary>
        ///     Encrypts the password.
        /// </summary>
        /// <param name="password">The password.</param>
        /// <param name="salt">The salt.</param>
        /// <returns>System.String.</returns>
        public string EncryptPassword(string password, string salt)
        {
            password = Sha1Encrypt(password);
            password += salt;
            return Sha1Encrypt(password);
        }
    }
}